<template>
  <view class="wave-wrap" :style="customStyle" :class="fill ? 'fill' : ''" @touchstart="getWaveQuery">
    <slot></slot>
    <view class="ripple" :class="{ show: isWaving }" :style="rippleSty" />
  </view>
</template>

<script>
export default {
  props: {
    /**
     * 放在其它容器时候设置，否则都是该容器包裹其它容器
     */
    fill: {
      type: Boolean,
      default: false
    },
    /**
     * 波纹颜色
     */
    waveColor: {
      type: String,
      default: 'rgba(0, 0, 0, 0.15)'
    },
    /**
     * 是否每次点击都重新获取容器尺寸，静态内容不需要qian
     * 默认为false，即只获取一次容器尺寸，如果容器尺寸变化，需要设置为true
     */
    update: {
      type: Boolean,
      default: false
    },
    customStyle: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      flag: false,
      rippleToTop: 0,
      rippleToLeft: 0,
      domInfo: {},
      isWaving: false
    }
  },
  computed: {
    rippleSty() {
      return {
        top: `${this.rippleToTop}px`,
        left: `${this.rippleToLeft}px`,
        width: `${this.domInfo.targetWidth}px`,
        height: `${this.domInfo.targetWidth}px`,
        backgroundColor: this.waveColor
      }
    }
  },
  methods: {
    throttle(fc, waitTime = 630, imme = false) {
      if (imme) {
        if (!this.flag) {
          this.flag = true
          typeof fc === 'function' && fc()
          setTimeout(() => {
            this.flag = false
          }, waitTime)
        }
      }
      else {
        if (!this.flag) {
          this.flag = true
          setTimeout(() => {
            this.flag = false
            typeof fc === 'function' && fc()
          }, waitTime)
        }
      }
    },
    async getWaveQuery(e) {
      if (this.isWaving) return
      await this.getElQuery()
      let touchesX = ''
      let touchesY = ''
      // #ifndef MP-BAIDU || MP-ALIPAY
      touchesX = e.touches[0].clientX
      touchesY = e.touches[0].clientY
      // #endif
      // #ifdef MP-BAIDU
      touchesX = e.changedTouches[0].clientX
      touchesY = e.changedTouches[0].clientY
      // #endif
      // #ifdef MP-ALIPAY
      touchesX = e.detail.clientX
      touchesY = e.detail.clientY
      // #endif
      this.rippleToTop = touchesY - this.domInfo.top - this.domInfo.targetWidth / 2
      this.rippleToLeft = touchesX - this.domInfo.left - this.domInfo.targetWidth / 2
      this.isWaving = true
      this.throttle(() => {
        this.isWaving = false
      })
    },
    getElQuery() {
      return new Promise(resolve => {
        if (!this.update && this.domInfo.top) {
          return resolve(this.domInfo)
        }
        let queryInfo = ''
        queryInfo = uni.createSelectorQuery().in(this)
        // #ifdef MP-ALIPAY
        queryInfo = uni.createSelectorQuery()
        // #endif
        queryInfo.select('.wave-wrap').boundingClientRect()
        queryInfo.exec(res => {
          const data = res[0]
          if (!data.width || !data.width) return
          data.targetWidth = data.height > data.width ? data.height : data.width
          if (!data.targetWidth) return
          this.domInfo = data
          resolve(data)
        })
      })
    }
  }
}
</script>

<style scoped>
.wave-wrap {
  display: flex;
  position: relative;
  width: max-content;
  overflow: hidden;
}

.fill {
  /* position: absolute;
  left: 0;
  top: 0; */
  width: 100%;
  height: 100%;
}

.ripple {
  position: absolute;
  border-radius: 999px;
  transform: scale(0);
  opacity: 1;
  pointer-events: none;
}

.ripple.show {
  opacity: 0;
  transform: scale(2);
  transition:
    opacity 0.6s linear,
    transform 0.6s linear;
  /* animation: ripple 0.75s ease-out; */
}

@keyframes ripple {
  to {
    transform: scale(2);
    opacity: 0;
  }
}
</style>
